package com.yuyou.fn.educational.service.impl;

import com.github.wens.mybatisplus.examples.Example;
import com.yuyou.fn.common.rocketmq.Consumer;
import com.yuyou.fn.common.util.BigDecimals;
import com.yuyou.fn.educational.entity.AttendClassRecord;
import com.yuyou.fn.educational.entity.ClassLecture;
import com.yuyou.fn.educational.entity.CourseClass;
import com.yuyou.fn.educational.entity.StudentReg;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.settlement.constant.Subjects;
import com.yuyou.fn.settlement.entity.ChangeRecord;
import com.yuyou.fn.settlement.service.ISettlementService;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

@Service
public class CourseConsumeServiceImpl implements ICourseConsumeService,ApplicationContextAware{

    private final static Logger log = LoggerFactory.getLogger(CourseConsumeServiceImpl.class);

    @Resource
    private IAttendClassRecordService attendClassRecordService ;

    @Resource
    private ISettlementService settlementService ;

    @Resource
    private IStudentRegService studentRegService ;

    @Resource
    private ICourseClassService courseClassService ;

    @Resource
    private IClassLectureService classLectureService ;

    @Resource
    private Redisson redisson ;

    @Resource
    private Consumer consumer;

    private ApplicationContext applicationContext ;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext ;
    }

    @PostConstruct
    public void init(){


    }

    @Transactional
    @Override
    public void consumeForAttendClassRecord(AttendClassRecord attendClassRecord) {
        //查找报名记录
        ClassLecture classLecture = classLectureService.findById(attendClassRecord.getClassLectureId());
        CourseClass courseClass = courseClassService.findById(classLecture.getClassId());
        if (courseClass==null){
            return;
        }

        StudentReg studentReg = studentRegService.findById(attendClassRecord.getRegId());

        if(studentReg == null ){
            return;
        }

        if(studentReg.getRegStatus() != 0 || studentReg.getChargingStatus() == 0 ){
            return;
        }

        RLock lock = redisson.getLock(String.format("consume:%d", studentReg.getRegId()));

        if(lock.tryLock()){
            try{
                //已经扣减预收
                List<ChangeRecord> consumeFutureIncomeChangeRecordList = settlementService.findChangeRecordsByTradeIdSubjectDirection(studentReg.getRegId(), Subjects.FUTURE_INCOME, 1);
                BigDecimal deductedFutureIncomeAmount = toSum(consumeFutureIncomeChangeRecordList) ;

                int unconsumeLecture = countUnconsumeLecture(studentReg.getRegId());//未消耗讲次

                BigDecimal refundAmount = studentReg.getRefundAmount();

                if(refundAmount == null ){
                    refundAmount = BigDecimal.ZERO;
                }

                //每一讲消耗
                BigDecimal  eachLectureAmount  = BigDecimals.calProportion(studentReg.getTotalAmount().subtract(refundAmount).subtract(deductedFutureIncomeAmount), new BigDecimal(1), new BigDecimal(unconsumeLecture));

                //不能大于学生已缴总额
                if(BigDecimals.compare( studentReg.getPayAmount().subtract(refundAmount) , deductedFutureIncomeAmount.add(eachLectureAmount) ) >= 0 ){

                    //设置财务标记
                    AttendClassRecord update  = new AttendClassRecord() ;
                    update.setFinanceFlag(1);
                    Example<AttendClassRecord> attendClassRecordExample = AttendClassRecord.createExample();
                    attendClassRecordExample.createCriteria().andEqualTo("attendClassRecordId" ,attendClassRecord.getAttendClassRecordId() ).andEqualTo("isAttendance",1).andEqualTo("financeFlag" , 0 );
                    if(attendClassRecordService.updateSelectiveByExample(update, attendClassRecordExample )){
                        settlementService.bookConsumeCourse(classLecture.getClassDate(),courseClass.getBusTeamId(),eachLectureAmount,courseClass.getClassName()+"|第" +  classLecture.getLectureNo() + "讲|"+ studentReg.getStudentName() ,courseClass.getClassId(),classLecture.getClassLectureId(),studentReg.getRegId(),studentReg.getStudentId());
                    }
                }
            }finally {
                lock.unlock();
            }
        }
    }


    private BigDecimal toSum(List<ChangeRecord> changeRecordList) {

        BigDecimal amount  = new BigDecimal(0);
        for(ChangeRecord changeRecord : changeRecordList ){
            amount = amount.add(changeRecord.getAmount());
        }
        return amount ;
    }

    private int countUnconsumeLecture(Long regId ){
        Example<AttendClassRecord> example = AttendClassRecord.createExample();
        example.createCriteria().andEqualTo("financeFlag" , 0 ).andEqualTo("regId",regId );
        return (int)attendClassRecordService.countByExample(example);
    }
}
